package com.example.thread;

// DeadlockExample06相比DeadlockExample05，我主要是想说明，其实NonReentrantLock02它并不用继承Lock。当然你想继承Lock也可以，那样看起来规范一点。
public class DeadlockExample06 {

    // 使用不可重入锁的两个线程
    public static void main(String[] args) {
        NonReentrantLock02 lock = new NonReentrantLock02();

        // 这个执行的时候会发生死锁现象。
        Thread thread1 = new Thread(() -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "获取了锁");
                // 再次尝试获取同一个锁，会导致死锁
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "再次获取了锁");
                lock.unlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 这个执行时不会发生死锁现象。
        Thread thread2 = new Thread(() -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "获取了锁");
                lock.unlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }
}

// 定义一个不可重入锁
// 相比DeadlockExample05中的来说，你会发现，定义自己的不可重入锁，不继承Lock也行。
class NonReentrantLock02 {
    private boolean isLocked = false;

    public synchronized void lock() throws InterruptedException {
        while (isLocked) {
            wait();
        }
        isLocked = true;
    }

    public synchronized void unlock() {
        isLocked = false;
        notify();
    }
}


